﻿using HP.HPTRIM.SDK;
using System;
using System.Collections.Generic;
using System.Net;
using System.Web.Script.Serialization;
using System.Windows.Forms;

namespace FolderGenerator
{
    public class FolderGeneratorAddin : ITrimAddIn
    {
        /// <summary>
        /// Retrieves a handle to the desktop window. TRIM UI components require the handle of a parent window
        /// </summary>
        /// <returns></returns>
        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        public static extern IntPtr GetDesktopWindow();

        public class MyMenuLink : TrimMenuLink
        {

            public override string Description
            {
                get { return "Create a standard set of folders"; }
            }

            public override int MenuID
            {
                get { return 1; }
            }

            public override string Name
            {
                get { return "Create standard folders"; }
            }

            public override bool SupportsTagged
            {
                get { return false; }
            }
        }

        private string _json = null;

        private FolderProfile[] _folderProfiles = null;

        private void getJson(Database database)
        {
            using (WebClient wc = new WebClient())
            {
                _json = wc.DownloadString(database.WebServerURL.TrimEnd('/') + "/CustomData/folders.json");

            }
        }

        /// <summary>
        /// Parse the JSON fetched previously to get the set of standard child folders for this Record type.
        /// </summary>
        /// <param name="forObject"></param>
        private void setFolderProfiles(TrimMainObject forObject)
        {
            
            using (Database database = forObject.Database)
            {
                // For this purpose I like the built-in JSON serializer JavaScriptSerializer as it:
                // - is simple to use, and
                // does not require any extra dependencies.
                // It does require us to have a type to deserialize to (e.g. FolderProfile) but I think that is cleaner than
                //  a dynamic approach.
                Dictionary<string, FolderProfile[]> folders = new JavaScriptSerializer()
                    .Deserialize<Dictionary<string, FolderProfile[]>>(_json);

                if (folders.ContainsKey((forObject as Record).RecordType.Name))
                {
                    _folderProfiles = folders[(forObject as Record).RecordType.Name];
                }
            }

        }



        public override string ErrorMessage
        {
            get { return ""; }
        }

        public override void ExecuteLink(int cmdId, TrimMainObjectSearch forTaggedObjects)
        {
            //   throw new NotImplementedException();
        }

        public override void ExecuteLink(int cmdId, TrimMainObject forObject, ref bool itemWasChanged)
        {
            try
            {
                // if we get this far then then IsMenuItemEnabled must have passed and we can assume we have one or more
                // folder profiles, so we go agead and create the contained folders.
                TrimURIList uris = new TrimURIList() { forObject.Uri };

                using (Database database = forObject.Database)
                {
                    foreach (FolderProfile folderProfile in _folderProfiles)
                    {
                        Record newFolder = new Record(new RecordType(database, folderProfile.RecordRecordType));
                        newFolder.Title = folderProfile.RecordTitle;
                        newFolder.Container = forObject as Record;
                        newFolder.Save();

                        uris.Add(newFolder.Uri);
                    }

                    // This is optional, maybe you prefer to show a 'finished' message, or just leave it to the user
                    // to notice the child folders have been added.
                    TrimMainObjectSearch search = new TrimMainObjectSearch(database, BaseObjectTypes.Record);
                    search.SelectByUris(uris);

                    ObjectSelector.DisplayResults(GetDesktopWindow(), search);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }



        public override TrimMenuLink[] GetMenuLinks()
        {
            return new TrimMenuLink[] { new MyMenuLink() };
        }

        public override void Initialise(Database db)
        {
            getJson(db);
        }

        public override bool IsMenuItemEnabled(int cmdId, TrimMainObject forObject)
        {
            // if the custom data does not contain any folder profiles for this Record Type
            // then the menu item will be disabled.
            setFolderProfiles(forObject);
            return _folderProfiles != null;
        }

        public override void PostDelete(TrimMainObject deletedObject)
        {
            // throw new NotImplementedException();
        }

        public override void PostSave(TrimMainObject savedObject, bool itemWasJustCreated)
        {
            // throw new NotImplementedException();
        }

        public override bool PreDelete(TrimMainObject modifiedObject)
        {
            return true;
        }

        public override bool PreSave(TrimMainObject modifiedObject)
        {
            return true;
        }

        public override bool SelectFieldValue(FieldDefinition field, TrimMainObject trimObject, string previousValue)
        {
            return false;
        }

        public override void Setup(TrimMainObject newObject)
        {
            //    throw new NotImplementedException();
        }

        public override bool SupportsField(FieldDefinition field)
        {
            return true;
        }

        public override bool VerifyFieldValue(FieldDefinition field, TrimMainObject trimObject, string newValue)
        {
            return true;
        }
    }
}
